package com.wteam.dragon.model.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wteam.dragon.model.mapper.*;
import com.wteam.dragon.model.pojo.bean.*;
import com.wteam.dragon.model.pojo.dto.RoleSmallDto;
import com.wteam.dragon.model.service.RolesMenusService;
import com.wteam.dragon.system.basebean.bean.ResultMessage;
import com.wteam.dragon.system.exception.BadRequestException;
import com.wteam.dragon.system.util.UserUtil;
import com.wteam.dragon.system.util.ValidationUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author 陈晓辉
 * @Date 2020/4/2 9:38
 */
@Service
@RequiredArgsConstructor
public class RolesMenusServiceImpl implements RolesMenusService {
    private final RolesMenusMapper rolesMenusMapper;
    private final UsersRolesMapper usersRolesMapper;
    private final RoleMapper roleMapper;
    private final MenuMapper menuMapper;
    private final UserMapper userMapper;
    private final RoleSmallDtoMapper roleSmallDtoMapper;


    @Override
    @Caching(evict = {@CacheEvict(value = "menusTree", allEntries = true),
            @CacheEvict(value = "Authorities", allEntries = true)})
    public ResultMessage editRolesMenus(Long roleId, Set<Long> menuIds) {
        ValidationUtil.isNull("roleId", roleId);
        if(menuIds == null || menuIds.size() == 0){
            throw new BadRequestException("menuIds不能为空");
        }
        QueryWrapper<UsersRoles> usersRolesQueryWrapper = new QueryWrapper<>();
        usersRolesQueryWrapper.lambda().eq(UsersRoles::getUserId, UserUtil.getCurrentUserId());
        List<UsersRoles> usersRolesList = usersRolesMapper.selectList(usersRolesQueryWrapper);
        List<Role> roleList = usersRolesList.stream().map(usersRoles -> roleMapper.selectById(usersRoles.getRoleId())).collect(Collectors.toList());
        boolean isAdmin = roleList.stream().anyMatch(role -> "admin".equals(role.getName()));
        if(!isAdmin){
            Role oneRole = roleMapper.selectById(roleId);
            checkLevel(oneRole.getLevel());
            //验证添加的权限是否是自己有的权限
            List<Long> myMenuIdList = new ArrayList<>();
            for (Role role : roleList) {
                QueryWrapper<RolesMenus> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(RolesMenus::getRoleId, role.getId());
                List<RolesMenus> rolesMenusList = rolesMenusMapper.selectList(queryWrapper);
                myMenuIdList.addAll(rolesMenusList.stream()
                        .map(rolesMenus -> menuMapper.selectById(rolesMenus.getMenuId())).map(Menu::getId).collect(Collectors.toList()));
            }
            if(myMenuIdList.size() < menuIds.size()){
                throw new BadRequestException("您不能添加不属于您的权限");
            }else{
                List<Long> residueMenuId = menuIds.stream()
                        .filter(menuId -> myMenuIdList.stream().noneMatch(myMenuId -> myMenuId.equals(menuId)))
                        .collect(Collectors.toList());
                if(residueMenuId.size() > 0){
                    throw new BadRequestException("您不能添加不属于您的权限");
                }
            }
        }
        QueryWrapper<RolesMenus> rolesMenusQueryWrapper = new QueryWrapper<>();
        rolesMenusQueryWrapper.lambda().eq(RolesMenus::getRoleId, roleId);
        List<RolesMenus> rolesMenusList = rolesMenusMapper.selectList(rolesMenusQueryWrapper);
        List<Long> oldMenusId = rolesMenusList.stream().map(RolesMenus::getMenuId).collect(Collectors.toList());
        //求交集(不变的)
        List<Long> in = oldMenusId.stream().filter(menuIds::contains).collect(Collectors.toList());
        //删除的
        oldMenusId.removeAll(in);
        oldMenusId.forEach(oldMenuId -> {
            QueryWrapper<RolesMenus> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(RolesMenus::getMenuId, oldMenuId)
                    .eq(RolesMenus::getRoleId, roleId);
            rolesMenusMapper.delete(queryWrapper);
        });
        //添加的
        menuIds.removeAll(in);
        menuIds.forEach(menuId -> {
            RolesMenus rolesMenus = new RolesMenus();
            rolesMenus.setRoleId(roleId);
            rolesMenus.setMenuId(menuId);
            rolesMenusMapper.insert(rolesMenus);
        });
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setStatus(HttpStatus.OK.value());
        resultMessage.setMessage("添加成功");
        return resultMessage;
    }

    /**
     * 检查用户权限 (将传进去的等级与当前用户等级进行比较)
     * @param level
     * @return
     */
    public void checkLevel(Integer level) {
        //获得当前用户的最高等级
        User currentUser = userMapper.selectById(UserUtil.getCurrentUserId());
        QueryWrapper<UsersRoles> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UsersRoles::getUserId, currentUser.getId());
        List<UsersRoles> usersRolesList = usersRolesMapper.selectList(queryWrapper);
        Optional<Integer> currentMax = usersRolesList.stream()
                .map(usersRoles -> roleSmallDtoMapper.selectById(usersRoles.getRoleId()))
                .map(RoleSmallDto::getLevel).min(Comparator.naturalOrder());
        if(!currentMax.isPresent()){
            throw new BadRequestException("您属于无角色用户,不可以进行任何操作");
        }
        //进行比较
        if(currentMax.get().compareTo(level) >= 0){
            throw new BadRequestException("权限级别不足，您的权限级别" + currentMax.get() + "低于等于权限级别" + level);
        }
    }


}
